package com.gjxx.netty;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class MyNettyServer {

    public void startNettyServer(int port) {
        /*
         * 配置服务端的NIO线程组
         * NioEventLoopGroup 是用来处理I/O操作的Reactor线程组
         * bossGroup：用来接收进来的连接，workerGroup：用来处理已经被接收的连接,进行socketChannel的网络读写，
         * bossGroup接收到连接后就会把连接信息注册到workerGroup
         * workerGroup的EventLoopGroup默认的线程数是CPU核数的二倍
         */
        EventLoopGroup bossGroup = new NioEventLoopGroup(3);
        EventLoopGroup workerGroup = new NioEventLoopGroup();

        try {
            // ServerBootstrap 是一个启动NIO服务的辅助启动类
            ServerBootstrap serverBootstrap = new ServerBootstrap();
            // 设置group，将bossGroup， workerGroup线程组传递到ServerBootstrap
            serverBootstrap = serverBootstrap.group(bossGroup, workerGroup);
            // ServerSocketChannel是以NIO的selector为基础进行实现的，用来接收新的连接，这里告诉Channel通过NioServerSocketChannel获取新的连接
            serverBootstrap = serverBootstrap.channel(NioServerSocketChannel.class);
            // 初始化通道，主要用于网络I/O事件，记录日志，编码、解码消息
            serverBootstrap = serverBootstrap.childHandler(new MyNettyChannelInitializer());

            // 绑定端口，同步等待成功 绑定的服务器
            ChannelFuture  futureTcp = serverBootstrap.bind(port).sync();
            futureTcp.addListener(future -> {
                if (future.isSuccess()) {
                    log.info("netty server 启动成功!" + port);
                } else {
                    log.info("netty server 启动失败!" + port);
                }
            });
            // 等待服务器监听端口关闭
            futureTcp.channel().closeFuture().sync();
        } catch (Exception e) {
            log.error("netty server 启动异常! " + e.getMessage());
            e.printStackTrace();
        } finally {
            // 退出，释放线程池资源
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
}
